package com.itheima.web;

import com.itheima.domain.Syslog;
import com.itheima.service.SyslogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

@Component
@SuppressWarnings("all")

public class LogAop {
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private SyslogService sysLogService;

    private Date visitTime; //开始时间
    private Class clazz; //访问的类
    private Method method;//访问的方法

    //前置通知  主要是获取开始时间，执行的类是哪一个，执行的是哪一个方法

    public void doBefore(JoinPoint jp) {

        try {
            visitTime = new Date();//当前时间就是开始访问的时间
            clazz = jp.getTarget().getClass(); //具体要访问的类
            String methodName = jp.getSignature().getName(); //获取访问的方法的名称
            Object[] args = jp.getArgs();//获取访问的方法的参数

            //获取具体执行的方法的Method对象
            if (args == null || args.length == 0) {
                method = clazz.getMethod(methodName); //只能获取无参数的方法
            } else {
                Class[] classArgs = new Class[args.length];
                for (int i = 0; i < args.length; i++) {
                    if (args[i] instanceof Model) {
                        classArgs[i] = Model.class;
                        continue;
                    }
                    classArgs[i] = args[i].getClass();
                }
                method = clazz.getMethod(methodName, classArgs);
            }
        } catch (Exception e) {
            System.out.println("************" + e.getMessage());
        }
    }

    //后置通知

    public void doAfter(JoinPoint jp) {
        System.out.println("后置来了");
        try {
            long time = new Date().getTime() - visitTime.getTime(); //获取访问的时长

            String url = "";
            //获取url
            if (clazz != null && method != null && clazz != LogAop.class) {
                //1.获取类上的@RequestMapping("/orders")
                RequestMapping classAnnotation = (RequestMapping) clazz.getAnnotation(RequestMapping.class);

                if (classAnnotation != null) {

                    String[] classValue = classAnnotation.value();

                    if(classValue!=null||classValue.length==0){

                        classValue=classAnnotation.path();
                    }
                    //2.获取方法上的@RequestMapping(xxx)
                    RequestMapping methodAnnotation = method.getAnnotation(RequestMapping.class);

                    if (methodAnnotation != null) {
                        String[] methodValue = methodAnnotation.value();

                        if(methodValue==null||methodValue.length==0){

                            methodValue=methodAnnotation.path();
                        }
                        url = classValue[0] + methodValue[0];
                        //获取访问的ip
                        String ip = request.getRemoteAddr();
                        //获取当前操作的用户
                        // 可以通过securityContext获取，也可以从request.getSession中获取
                        SecurityContext context = SecurityContextHolder.getContext();
                        String username = ((User) (context.getAuthentication().getPrincipal())).getUsername();
                        //String username = user.getUsername();
                        //将日志相关信息封装到SysLog对象

                        Syslog sysLog = new Syslog();
                        sysLog.setExecutionTime(time); //执行时长
                        sysLog.setIp(ip);
                        sysLog.setMethod("[方法名] " + method.getName());
                        sysLog.setUrl(url);
                        sysLog.setUsername(username);
                        sysLog.setVisitTime(visitTime);
                        //调用Service完成操作
                        sysLogService.save(sysLog);
                    }
                }
            }
        } catch (Exception e) {
            System.out.println("************" + e.getMessage());
        }
    }
}
